/* OpenTeddy 3d sketch modeler based on the paper by T. Igarashi et al.
 *      "Teddy: A Sketching Interface for 3D Freeform Design"
 *
 * Copyright (c) 2004 Alex Ni
 *
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/* OpenTeddy 3d sketch modeler based on the paper by T. Igarashi et al.
*      "Teddy: A Sketching Interface for 3D Freeform Design"
*
* Copyright (c) 2004 Alex Ni
*/


#include "otconfig.h"

#include "GTS/gts.h"

#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <string>

extern "C"
{
#include "triangle.h"
#include "trackball.h"
}

// C++
#include <map>
#include <list>
#include <deque>
#include <vector>

// Our includes
#include "main.h"
#include "pub_infl.h"

#include "../glfw/win32/glfw.h"

std::map<std::string, char*> g_ot_pref_hash;
std::list<char*> g_ot_pref_allocd_strs;

bool ot_pref_exists(char *s)
{
	if (g_ot_pref_hash.find(s) == g_ot_pref_hash.end()) return false;
	return true;
}

bool ot_get_pref_double_check(char* s, double* d, double defval)
{
	OT_ASSERT(d);

	if (!ot_pref_exists(s) || ( sscanf(g_ot_pref_hash[s], "%lf", d) != 1) )
	{
		*d = defval;
		return false;
	}
	return true;
}

bool ot_get_pref_int_check(char* s, int* d, double defval)
{
	OT_ASSERT(d);

	if (!ot_pref_exists(s) || ( sscanf(g_ot_pref_hash[s], "%d", d) != 1) )
	{
		*d = defval;
		return false;
	}
	return true;
}

bool ot_chars_to_double(char* s, double* d)
{
	char sstr[3];
	sstr[0] = s[0]; sstr[1] = s[1]; sstr[2] = '\0';
	int i;
	if ( sscanf(sstr, "%x", &i) == 1 )
	{
		*d = (1.0 * i) / 255.0;
		return true;
	}
	return false;
}

bool ot_str_to_rgb(char* s, OT3vec* d)
{
	if (strlen(s) != 6) return false;
	int i = 0;
	while (*s)
	{
		if (!ot_chars_to_double(s, &((*d)[i++]))) return false;
		s += 2;
	}
	return true;
}

bool ot_get_pref_rgb_check(char* s, OT3vec* d, OT3vec defval)
{
	OT_ASSERT(d);

	if (!ot_pref_exists(s) || !ot_str_to_rgb(g_ot_pref_hash[s], d) )
	{
		*d = defval;
		return false;
	}
	return true;
}

OT3vec ot_get_pref_rgb(char* s, OT3vec defval)
{
	OT3vec toreturn;
	ot_get_pref_rgb_check(s, &toreturn, defval);
	return toreturn;
}

double ot_get_pref_double(char* s, double defval)
{
	double toreturn;
	ot_get_pref_double_check(s, &toreturn, defval);
	return toreturn;
}

int ot_get_pref_int(char* s, double defval)
{
	int toreturn;
	ot_get_pref_int_check(s, &toreturn, defval);
	return toreturn;
}

void ot_set_rgb(OT3vec rgb, double a)
{
	glColor4f(rgb[0], rgb[1], rgb[2], a);
}

#define OT_MAX_PREF_STRLEN 256
static char* ot_pref_strcpy(const char* s)
{
	int sl = strlen(s);
	OT_ASSERT((sl > 0) && (sl < OT_MAX_PREF_STRLEN));

	char *sc = new char[sl + 1];
	strcpy(sc, s);
	sc[sl] = '\0';

	g_ot_pref_allocd_strs.push_back(sc);

	return sc;
}

static void ot_pref_parser_start_node_cb (GMarkupParseContext *context,
	const gchar	*node_name,
	const gchar	**attribute_names,
	const gchar	**attribute_values,
	gpointer	user_data,
	GError	**error)
{
	// Note, attributes are temporarily allocated- we have to make our own copies.

	for (int i = 0; attribute_names[i] != NULL; i++)
	{
		printf("PREF %s is %s\n", attribute_names[i], attribute_values[i] );
		g_ot_pref_hash[ot_pref_strcpy(attribute_names[i])] =
			ot_pref_strcpy(attribute_values[i]);
	}
}

static void ot_read_prefs()
{
	
}
